package com.ljx.mediatorPatternMode;

import lombok.Data;

/**
 *
 * 中介者模式（复杂案例）
 *
 * 定义：
 * 又叫调停模式，定义一个中介角色来封装一系列对象之间的交互，使原有对象之间的耦合松散，且可以独立地改变它们之间的交互
 *
 * 优点：
 * **松散耦合
 * 中介者模式通过把多个同事对象之间的交互封装到中介者对象里面，从而使得同事对象之间松散耦合，
 * 基本上可以做到互补依赖。这样一来，同事对象就可以独立地变化和复用，而不再像以前那样“牵一处而动全身”了。
 * **集中控制交互
 * 多个同事对象的交互，被封装在中介者对象里面集中管理，使得这些交互行为发生变化的时候，
 * 只需要修改中介者对象就可以了，当然如果是已经做好的系统，那么就扩展中介者对象，而各个同事类不需要做修改。
 * **一对多关联转变为一对一的关联
 * 没有使用中介者模式的时候，同事对象之间的关系通常是一对多的，引入中介者对象以后，
 * 中介者对象和同事对象的关系通常变成双向的一对一，这会让对象的关系更容易理解和实现。
 *
 * 缺点：**
 * 当同事类太多时，中介者的职责将很大，它会变得复杂而庞大，以至于系统难以维护。
 *
 *
 * 使用场景：
 * 系统中对象之间存在复杂的引用关系，系统结构混乱且难以理解。
 * 当想创建一个运行于多个类之间的对象，又不想生成新的子类时
 *
 * 经典案例：
 * MVC 框架，其中C（控制器）就是 M（模型）和 V（视图）的中介者
 *
 * @作者 LJX
 * @日期 2022/12/26 14:23
 */
public class MediatorPatternComplexTest {

    public static void main(String[] args) {

        //创建中介
        Intermediary intermediary = new Intermediary();

        //房东和租客找中介
        Landlord landlord = new Landlord("卢佳曦", intermediary);
        Tenant tenant = new Tenant("打工人", intermediary);

        //中介登记
        intermediary.setLandlord(landlord);
        intermediary.setTenant(tenant);

        tenant.contract("想租房子！！！");
        landlord.contract("我有房子！！！");
    }

}

/**
 * 抽象中介者
 */
abstract class Mediator{
    //客户与中介联络的方法
    abstract void contract(String msg, Person person);
}

/**
 * 具体中介者
 */
@Data
class Intermediary extends Mediator{

    Tenant tenant;

    Landlord landlord;

    @Override
    void contract(String msg, Person person) {
        //如果是房主，则租客获得信息
        if(person instanceof Landlord){
            tenant.getMsg(msg);
        }
        //如果是租客，则房主获得信息
        if(person instanceof Tenant){
            landlord.getMsg(msg);
        }
    }
}

/**
 * 抽象同事
 */
@Data
abstract class Person{

    protected String name;
    protected Mediator mediator;

    /**
     * 和中介联系
     * @param msg
     */
    abstract void contract(String msg);

    /**
     * 获取信息
     * @param msg
     */
    abstract void getMsg(String msg);

    public Person(String name, Mediator mediator) {
        this.name = name;
        this.mediator = mediator;
    }
}

/**
 * 租客（具体同事）
 */
class Tenant extends Person{

    public Tenant(String name, Mediator mediator) {
        super(name, mediator);
    }

    @Override
    void contract(String msg) {
        mediator.contract(msg, this);
    }

    @Override
    void getMsg(String msg) {
        System.out.println("租客" + name + "获取的信息：" + msg);
    }
}

/**
 * 房东（具体同事）
 */
class Landlord extends Person{

    public Landlord(String name, Mediator mediator) {
        super(name, mediator);
    }

    @Override
    void contract(String msg) {
        mediator.contract(msg, this);
    }

    @Override
    void getMsg(String msg) {
        System.out.println("房东" + name + "获取的信息：" + msg);
    }
}
